package id.web.faisalabdillah.xtimesheet.web.ws;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import id.web.faisalabdillah.xtimesheet.domain.FileStorage;
import id.web.faisalabdillah.xtimesheet.services.IFileStorageService;
import id.web.faisalabdillah.xtimesheet.web.dto.DTOJsonResult;
import id.web.faisalabdillah.xtimesheet.web.model.FileStorageModel;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.appengine.api.datastore.Blob;

@Controller
@RequestMapping(value="/service/file_storage")
public class FileStorageServiceCtrl {

	@Autowired
	private IFileStorageService fileStorageService;

	/**
	 * Get FileStorage By ID
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/id/{id}",method=RequestMethod.GET)
	public @ResponseBody
	DTOJsonResult<FileStorage> findById(@PathVariable long id) {
		DTOJsonResult<FileStorage> data = new DTOJsonResult<FileStorage>();

		FileStorage fs;
		try {
			fs = fileStorageService.findById(id);
			data.setData(fs);
			data.setSuccess(true);
			data.setResultSize(1);
			data.setError("");
		} catch (Exception e) {
			data.setSuccess(false);
			data.setError(e.getMessage());
		}
		return data;
	};

	/**
	 * Get File Storage By Codename
	 * @param codename
	 * @return
	 */
	@RequestMapping(value="/codename/{codename}",method=RequestMethod.GET)
	public @ResponseBody
	DTOJsonResult<FileStorage> findByCodeName(@PathVariable String codename) {
		DTOJsonResult<FileStorage> data = new DTOJsonResult<FileStorage>();

		FileStorage fs;
		try {
			fs = fileStorageService.findByCodename(codename);
			data.setData(fs);
			data.setSuccess(true);
			data.setResultSize(1);
			data.setError("");
		} catch (Exception e) {
			data.setSuccess(false);
			data.setError(e.getMessage());
		}
		return data;
	}
	
	/**
	 * list All FileStorage
	 * @return
	 */
	@RequestMapping(value="/all",method=RequestMethod.GET)
	public @ResponseBody DTOJsonResult<List<FileStorage>> listAll(){
		DTOJsonResult<List<FileStorage>> data = new DTOJsonResult<List<FileStorage>>();
		try {
			data.setData(fileStorageService.listAll());
			data.setSuccess(true);
			data.setResultSize(fileStorageService.sizeAll());
			data.setError("");
		} catch (Exception e) {
			data.setSuccess(false);
			data.setError(e.getMessage());
		}
		return data;
	}
	
	/**
	 * List Paging FileStorage
	 * @param first
	 * @param max
	 * @return
	 */
	@RequestMapping(value="/all/{first}/{max}",method=RequestMethod.GET)
	public @ResponseBody DTOJsonResult<List<FileStorage>> pagingAll(@PathVariable int first,@PathVariable int max){
		DTOJsonResult<List<FileStorage>> data = new DTOJsonResult<List<FileStorage>>();
		try {
			data.setData(fileStorageService.listPaging(first, max));
			data.setSuccess(true);
			data.setResultSize(fileStorageService.sizeAll());
			data.setError("");
		} catch (Exception e) {
			e.printStackTrace();
			data.setSuccess(false);
			data.setError(e.getMessage());
		}
		return data;
	}
	
	@RequestMapping(value="/delete/{id}",method=RequestMethod.GET)
	public @ResponseBody DTOJsonResult<Object> delete(@PathVariable long id){
		DTOJsonResult<Object> data=new DTOJsonResult<Object>();
		try {
			fileStorageService.remove(id);
			data.setSuccess(true);
		} catch (Exception e) {
			data.setSuccess(false);
			data.setError(e.getMessage());
		}
		return data;
	}
	
	@RequestMapping(value="/insert",method=RequestMethod.POST)
	public @ResponseBody DTOJsonResult<Object> insert(FileStorageModel fileStorageModel,BindingResult result){
		DTOJsonResult<Object> data=new DTOJsonResult<Object>();
		if (result.hasErrors()) {
			String errors="";
            for (ObjectError error : result.getAllErrors()) {
            	errors+="Error: " + error.getCode() + " - "
                + error.getDefaultMessage()+"\n";
            }
            data.setError(errors);
            data.setSuccess(false);
            return data;
		}
		try {
			FileStorage fileStorage=new FileStorage();
			fileStorage.setCodename(fileStorageModel.getCodename());
			fileStorage.setContentType(fileStorageModel.getFile().getContentType());
			fileStorage.setFile_name(fileStorageModel.getFile().getOriginalFilename());
			fileStorage.setFile(new Blob(fileStorageModel.getFile().getBytes()));
			fileStorage.setDescription(fileStorageModel.getDescription());
			fileStorageService.insert(fileStorage);
			data.setSuccess(true);
		} catch (Exception e) {
			data.setError(e.getMessage());
			data.setSuccess(false);
		}
		return data;
	}
	
	@RequestMapping(value="/download/{id}")
	public void download(@PathVariable long id,HttpServletResponse response){
		try {
			FileStorage fs=fileStorageService.findById(id);
			response.setContentType(fs.getContentType());
			response.setHeader("Content-Disposition","attachment; filename="+fs.getFile_name());
			ByteArrayInputStream bi=new ByteArrayInputStream(fs.getFile().getBytes());
			byte[] buff=new byte[1024];
			int num;
			while((num=bi.read(buff))>=0){
				response.getOutputStream().write(buff, 0, num);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@RequestMapping(value="/update/{id}",method=RequestMethod.POST)
	public @ResponseBody DTOJsonResult<Object> update(FileStorageModel fileStorageModel,BindingResult result,@PathVariable long id){
		DTOJsonResult<Object> data=new DTOJsonResult<Object>();
		if (result.hasErrors()) {
			String errors="";
            for (ObjectError error : result.getAllErrors()) {
            	errors+="Error: " + error.getCode() + " - "
                + error.getDefaultMessage()+"\n";
            }
            data.setError(errors);
            data.setSuccess(false);
            return data;
		}
		try {
			FileStorage fileStorage=new FileStorage();
			fileStorage.setId(id);
			fileStorage.setCodename(fileStorageModel.getCodename());
			fileStorage.setContentType(fileStorageModel.getFile().getContentType());
			fileStorage.setFile_name(fileStorageModel.getFile().getOriginalFilename());
			fileStorage.setFile(new Blob(fileStorageModel.getFile().getBytes()));
			fileStorageService.update(fileStorage);
			data.setSuccess(true);
		} catch (Exception e) {
			data.setError(e.getMessage());
			data.setSuccess(false);
		}
		return data;
	}
}
